package com.party.core.service.member.impl;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.party.common.paging.Page;
import com.party.common.utils.DateUtils;
import com.party.common.utils.PartyCode;
import com.party.core.dao.read.member.MemberActReadDao;
import com.party.core.dao.write.member.MemberActWriteDao;
import com.party.core.exception.BusinessException;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.ActStatus;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.member.*;
import com.party.core.model.order.OrderForm;
import com.party.core.model.order.OrderStatus;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.counterfoil.ICounterfoilService;
import com.party.core.service.member.IMemberActService;
import com.party.core.service.member.IPartnerMemberService;
import com.sun.istack.NotNull;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 活动报名实现
 * party
 * Created by wei.li
 * on 2016/9/18 0018.
 */

@Service
public class MemberActService implements IMemberActService, com.party.core.api.member.IMemberActService {

    @Autowired
    MemberActWriteDao memberActWriteDao;

    @Autowired
    MemberActReadDao memberActReadDao;

    @Autowired
    private IActivityService activityService;

    @Autowired
    private IPartnerMemberService partnerMemberService;

    @Autowired
    private ICounterfoilService counterfoilService;

    /**
     * 活动报名插入
     *
     * @param memberAct 活动报名
     * @return 插入结果（true/false）
     */
    @Override
    public String insert(MemberAct memberAct) {
        BaseModel.preInsert(memberAct);
        boolean result = memberActWriteDao.insert(memberAct);
        if (result) {
            return memberAct.getId();
        }
        return null;
    }

    /**
     * 活动报名更新
     *
     * @param memberAct 活动报名
     * @return 更新结果（true/false）
     */
    @Override
    public boolean update(MemberAct memberAct) {
        memberAct.setUpdateDate(new Date());
        return memberActWriteDao.update(memberAct);
    }

    /**
     * 逻辑删除活动报名
     *
     * @param id 实体主键
     * @return 删除结果（true/false）
     */
    @Override
    public boolean deleteLogic(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)) {
            return false;
        }
        return memberActWriteDao.deleteLogic(id);
    }

    /**
     * 物理删除活动报名
     *
     * @param id 实体主键
     * @return 删除结果（true/false）
     */
    @Override
    public boolean delete(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)) {
            return false;
        }
        return memberActWriteDao.delete(id);
    }

    /**
     * 批量逻辑删除活动报名
     *
     * @param ids 主键集合
     * @return 删除结果（true/false）
     */
    @Override
    public boolean batchDeleteLogic(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        return memberActWriteDao.batchDeleteLogic(ids);
    }

    /**
     * 批量物理删除活动报名
     *
     * @param ids 主键集合
     * @return 删除结果(true / false)
     */
    @Override
    public boolean batchDelete(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        return memberActWriteDao.batchDelete(ids);
    }

    /**
     * 根据主键获取活动报名
     *
     * @param id 主键
     * @return 活动报名信息
     */
    @Override
    public MemberAct get(String id) {
        return memberActReadDao.get(id);
    }


    /**
     * 根据会员和活动编号获取报名记录
     *
     * @param memberId   会员编号
     * @param activityId 活动编号
     * @return 报名记录
     */
    @Override
    public MemberAct findByMemberAct(String memberId, String activityId) {
        MemberAct memberAct = new MemberAct();
        memberAct.setMemberId(memberId);
        memberAct.setActId(activityId);

        List<MemberAct> memberActList = this.list(memberAct);
        if (CollectionUtils.isEmpty(memberActList)) {
            return null;
        }
        return memberActList.get(0);
    }

    /**
     * 分页查询活动报名
     *
     * @param memberAct 活动报名
     * @param page      分页信息
     * @return 活动报名信息列表
     */
    @Override
    public List<MemberAct> listPage(MemberAct memberAct, Page page) {
        return memberActReadDao.listPage(memberAct, page);
    }

    /**
     * 报名信息列表
     *
     * @param withBuyer 报名信息
     * @param page      分页参数
     * @return 报名信息列表
     */
    @Override
    public List<WithBuyer> withBuyerList(WithBuyer withBuyer, Page page) {
        return memberActReadDao.withBuyerList(withBuyer, page);
    }

    /**
     * 报名信息列表
     *
     * @param withBuyer 报名信息
     * @param page      分页参数
     * @return 报名信息列表
     */
    @Override
    public List<WithBuyer> withActivityList(WithBuyer withBuyer, Map<String, Object> params, Page page) {
        return memberActReadDao.withActivityList(withBuyer, params, page);
    }

    /**
     * 查询所有活动报名信息
     *
     * @param memberAct 活动报名信息
     * @return 活动报名信息列表
     */
    @Override
    public List<MemberAct> list(MemberAct memberAct) {
        return memberActReadDao.listPage(memberAct, null);
    }

    /**
     * 根据商铺商品编号查询报名信息
     *
     * @param id 商铺商品编号
     * @return 报名列表
     */
    @Override
    public List<MemberAct> listByStoreGoodsId(@NotNull String id, Page page) {
        if (!Strings.isNullOrEmpty(id)) {
            MemberAct memberAct = new MemberAct();
            memberAct.setStoreGoodsId(id);
            memberAct.setJoinin(YesNoStatus.YES.getCode());//报名
            List<MemberAct> memberActList = memberActReadDao.listPage(memberAct, page);
            return memberActList;
        }
        return Collections.EMPTY_LIST;
    }

    /**
     * 批量查询活动报名
     *
     * @param ids       主键集合
     * @param memberAct 活动报名信息
     * @param page      分页信息
     * @return 活动报名信息列表
     */
    @Override
    public List<MemberAct> batchList(@NotNull Set<String> ids, MemberAct memberAct, Page page) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.EMPTY_LIST;
        }
        return memberActReadDao.batchList(ids, new HashedMap(), page);
    }

    /**
     * 批量查询活动报名
     *
     * @param ids               主键集合
     * @param applyWithActivity 查询参数
     * @param page              分页信息
     * @return 活动报名信息列表
     */
    @Override
    public List<ApplyWithActivity> batchWithActivityList(Set<String> ids, ApplyWithActivity applyWithActivity, Page page) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.EMPTY_LIST;
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("title", applyWithActivity.getActivityTitle());
        param.put("checkStatus", applyWithActivity.getCheckStatus());
        return memberActReadDao.batchWithActivityList(ids, param, page);
    }

    @Override
    public List<MemberAct> activityMemberActs(MemberAct memberAct, Page page) {
        return memberActReadDao.activityListPage(memberAct, page);
    }

    /**
     * 查询报名数
     *
     * @param activityId 活动编号
     * @return 报名列表
     */
    @Override
    public List<MemberAct> findMemberNum(String activityId) {
        MemberAct memberAct = new MemberAct();
        memberAct.setActId(activityId);
        List<MemberAct> memberActList = this.list(memberAct);
        if (!CollectionUtils.isEmpty(memberActList)) {
            return memberActList;
        }
        return Collections.EMPTY_LIST;
    }

    @Override
    public List<MemberAct> webListPage(MemberAct memberAct, Map<String, Object> params, Page page) {
        return memberActReadDao.webListPage(memberAct, params, page);
    }

    /**
     * 报名列表
     *
     * @param memberAct 报名信息
     * @param params    查询信息
     * @param page      分页参数
     * @return 报名列表
     */
    @Override
    public List<WithBuyer> withMemberList(MemberAct memberAct, Map<String, Object> params, Page page) {
        return memberActReadDao.withMemberList(memberAct, params, page);
    }

    @Override
    public MemberAct findByOrderId(String orderId) {
        return memberActReadDao.findByOrderId(orderId);
    }

    /**
     * 取消报名
     *
     * @param orderForm 订单信息
     */
    @Override
    public void cancel(OrderForm orderForm) {
        MemberAct memberAct = this.findByOrderId(orderForm.getId());
        if (null != memberAct) {
            memberAct.setCheckStatus(ActStatus.ACT_STATUS_CANCEL.getCode());
            memberAct.setJoinin(YesNoStatus.NO.getCode()); // 取消
            this.update(memberAct);
        }
    }

    @Override
    public List<MemberAct> listPageTwo(MemberAct memberAct, Map<String, Object> params, Page page) {
        return memberActReadDao.listPageTwo(memberAct, params, page);
    }


    /**
     * 统计每天的报名数
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 统计结果
     */
    @Override
    public List<HashMap<String, Object>> countByDate(String startDate, String endDate) {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("startDate", startDate);
        parameter.put("endDate", endDate);
        return memberActReadDao.countByDate(parameter);
    }


    /**
     * 统计报名数
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param memberId  会员编号
     * @return
     */
    @Override
    public List<HashMap<String, Object>> countByDate(String startDate, String endDate, String memberId) {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("startDate", startDate);
        parameter.put("endDate", endDate);
        parameter.put("memberId", memberId);
        return memberActReadDao.countByDate(parameter);
    }

    /**
     * 统计报名数
     *
     * @param memberId    发布者
     * @param startDate   开始时间
     * @param endDate     结束时间
     * @param isCopartner 是否为合伙人
     * @return 统计数
     */
    @Override
    public Integer count(String memberId, String startDate, String endDate, boolean isCopartner) {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("startDate", startDate);
        parameter.put("endDate", endDate);
        parameter.put("memberId", memberId);
        parameter.put("isCopartner", isCopartner);
        Integer count = memberActReadDao.count(parameter);
        return null == count ? 0 : count;
    }

    /**
     * 统计报名数
     *
     * @param memberId    发布者
     * @param isCopartner 是否为合伙人
     * @return 统计数
     */
    @Override
    public Integer count(String memberId, boolean isCopartner) {
        return this.count(memberId, null, null, isCopartner);
    }

    /**
     * 所有待处理订单
     *
     * @return 统计数
     */
    @Override
    public Integer onHandCount() {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("status", OrderStatus.ORDER_STATUS_IN_REVIEW.getCode());
        return memberActReadDao.count(parameter);
    }

    /**
     * 所有报名
     *
     * @return 统计数
     */
    @Override
    public Integer allCount() {
        HashMap<String, Object> parameter = Maps.newHashMap();
        return memberActReadDao.count(parameter);
    }

    @Override
    public List<MemberAct> getSuccessMemberAct(MemberAct memberAct, Set<Integer> status) {
        return memberActReadDao.getSuccessMemberAct(memberAct, status);
    }

    public Integer getSuccessMemberAct(Map<String, Object> params) {
        Set<Integer> status = new HashSet<Integer>();
        status.add(ActStatus.ACT_STATUS_AUDIT_REJECT.getCode());
        status.add(ActStatus.ACT_STATUS_CANCEL.getCode());
        status.add(ActStatus.ACT_STATUS_NO_JOIN.getCode());
        params.put("delFlag", BaseModel.DEL_FLAG_NORMAL);
        params.put("status", status);
        return memberActReadDao.getSuccessMemberAct2(params);
    }


    /**
     * 报名者列表
     *
     * @param memberId 机构编号
     * @return 报名者
     */
    @Override
    public List<MemberAct> applicantList(String memberId) {
        return memberActReadDao.applicantList(memberId);
    }


    /**
     * 根据活动统计
     *
     * @param activityId 活动编号
     * @param status     状态
     * @return 统计数
     */
    @Override
    public Integer countByActivity(String activityId, Integer status) {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("activityId", activityId);
        parameter.put("status", status);
        return memberActReadDao.count(parameter);
    }

    /**
     * 查询某机构下的所有活动报名者
     *
     * @param partnerId
     * @return
     */
    @Override
    public List<Member> getActMembersByPartnerId(String partnerId) {
        return memberActReadDao.getActMembersByPartnerId(partnerId);
    }

    /**
     * 查询所有报名成功的数据
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllSuccessGroup(Integer status, String partnerId, String memberId) {
        return memberActReadDao.getAllSuccessGroup(status, partnerId, memberId);
    }

    /**
     * 活动报名
     *
     * @param parameter     报名请求参数
     * @param counterfoilId
     * @return 报名信息
     */
    @Override
    public MemberAct apply(MemberActApplyParameter parameter, String counterfoilId, String orgId) {
        //验证报名结束时间
        boolean isVerifyDate = DateUtils.afterTodayDate(parameter.getEndTime());
        if (!isVerifyDate) {
            throw new BusinessException(PartyCode.JOIN_ACT_ENDDATE_ERROR, "报名失败，报名时间晚于报名结束时间");
        }

        //验证人数上限
        Counterfoil counterfoil = counterfoilService.get(counterfoilId);
        if (null == counterfoil) {
            throw new BusinessException("票券不能为空");
        }
        if (counterfoil.getJoinNum() >= counterfoil.getLimitNum()) {
            throw new BusinessException(PartyCode.JOIN_ACT_LIMITNUM_ERROR, "报名失败，票券的报名人数上限已满");
        }

        MemberAct memberAct = new MemberAct();
        memberAct.setActId(parameter.getActivityId());
        memberAct.setMemberId(parameter.getMemberId());
        memberAct.setName(parameter.getRealname());
        memberAct.setMobile(parameter.getMobile());
        memberAct.setCompany(parameter.getCompany());
        memberAct.setJobTitle(parameter.getTitle());
        memberAct.setPayment(parameter.getPayment());
        memberAct.setUpdateBy(parameter.getMemberId());
        memberAct.setJoinin(YesNoStatus.YES.getCode());
        memberAct.setCollect(YesNoStatus.YES.getCode());
        memberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_PASS.getCode());
        memberAct.setOrderId(parameter.getOrderId());
        BaseModel.preByInfo(parameter.getMemberId(), memberAct);
        this.insert(memberAct);

        //机构用户
        PartnerMember partnerMember = new PartnerMember();
        partnerMember.setPartnerId(orgId);
        partnerMember.setMemberId(parameter.getMemberId());
        partnerMemberService.getSet(partnerMember);
        return memberAct;
    }


    @Override
    public List<Map<String, Object>> getAllSuccessGroupAPI(Integer status, String partnerId, String memberId) {
        return getAllSuccessGroup(status, partnerId, memberId);
    }

    @Override
    public Map<String, Object> findDataByDate(String startDate, String endDate, Map<String, Object> params) {
        return memberActReadDao.findDataByDate(startDate, endDate, params);
    }

    @Override
    public void deleteByActivityId(String activityId) {
        memberActWriteDao.deleteByActivityId(activityId);
    }

    @Override
    public Integer disCount(String memberId, String startDate, String endDate) {
        HashMap<String, Object> parameter = Maps.newHashMap();
        parameter.put("startDate", startDate);
        parameter.put("endDate", endDate);
        parameter.put("memberId", memberId);
        Integer count = memberActReadDao.disCount(parameter);
        return null == count ? 0 : count;
    }

    @Override
    public List<WithBuyer> listForDistribution(Map<String, Object> params, Page page) {
        return memberActReadDao.listForDistribution(params, page);
    }

    @Override
    public MemberAct getMyAct(String memberId, String activityId) {
        MemberAct memberAct = new MemberAct();
        memberAct.setMemberId(memberId);
        memberAct.setActId(activityId);
        return memberActReadDao.getMyAct(memberAct);
    }

    @Override
    public MemberAct getMyActFree(String memberId, String activityId, Integer counterfoilType) {
        return memberActReadDao.getMyActFree(memberId, activityId, counterfoilType);
    }

    @Override
    public List<Map<String, Object>> memberActlist(Map<String, Object> params) {
        return memberActReadDao.memberActlist(params);
    }

    @Override
    public MemberAct getMyActNoFree(String memberId, String activityId) {
        return memberActReadDao.getMyActNoFree(memberId, activityId);
    }

    @Override
    public Integer memberActCount(Map<String, Object> params) {
        return memberActReadDao.memberActCount(params);
    }

    @Override
    public List<Map<String, Object>> memberActlist2(Map<String, Object> params) {
        return memberActReadDao.memberActlist2(params);
    }

    @Override
    public Integer getSigninMemberCountByMemberGroupId(List<String> partnerIds,Map<String,Object> params) {
        return memberActReadDao.getSigninMemberCountByMemberGroupId(partnerIds,params);
    }
}
